package com.zhiwei.gateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.zhiwei.common.constant.ErrorEnum;
import com.zhiwei.common.constant.HttpConstants;
import com.zhiwei.common.constant.ResultResponseMsg;
import com.zhiwei.common.util.HttpUtil;
import com.zhiwei.gateway.service.UserTokenService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 前置参数处理器: 认证授权
 */
@Component
@Slf4j
public class PreParamFilter extends ZuulFilter {

    @Autowired
    private UserTokenService userTokenService;

    /**
     * 过滤器具体逻辑(作用于路由服务)
     */
    @SneakyThrows
    @Override
    public Object run() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest httpServletRequest = requestContext.getRequest();
        log.info("前置参数处理器 ----> 请求参数：{},地址：{}", HttpUtil.getRequestParamsStr(httpServletRequest), httpServletRequest.getRequestURL());
        String accessToken = HttpUtil.getRequestHeaderMap(httpServletRequest).get(HttpConstants.HEADER_TOKEN);
        if (null == userTokenService.getUserInfoByToken(accessToken)) {
            log.error("请求接口【{}】Token:【{}】无效", httpServletRequest.getRequestURI(), accessToken);
            //过滤该请求，不往下级服务去转发请求，请求处理流程到此结束
            requestContext.setSendZuulResponse(false);
            requestContext.getResponse().setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            requestContext.setResponseBody(ResultResponseMsg.buildResultMsg(ErrorEnum.HTTP_TOKEN, null).toString());
        }
        return null;
    }

    /**
     * 判断是否启用过滤器
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 过滤器执行顺序
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 过滤器类型：
     * pre 表示在请求被路由之前执行
     * post: 表示请求之后执行
     * error： 表示错误处理器
     * routing： 服务名映射处理器：服务名映射为具体服务
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }
}
